先來看看官方文檔的開頭介紹
The
ViewModel
class is designed to store and manage UI-related data in alifecycle
conscious way. TheViewModel
class allows data to survive configuration changes such as screen rotations.
重點大概是說,ViewModel
是一個用來儲存、管理數據,並可以感知 生命週期
的組件。
這邊推薦一個我覺得講解得不錯的影片 講者是妹子,架構組件之 ViewModel 介紹
裡面簡單介紹了 ViewModel
的優點、怎麼保存數據、共享數據、以及常犯的錯誤等等..
大家有空可以去看看,可以更快速的了解 ViewModel
。
以下是我把影片重點擷取出來的部分。
添加依賴
dependencies {
// ViewModel
implementation "androidx.lifecycle:lifecycle-extensions:2.0.0"
繼承 ViewModel
,這裡存放跟 UI 相關的數據和物件,這個 User 類別裡面就是用來放一些變數而已,就不貼出來了。
class MainViewModel : ViewModel() {
private lateinit var user: User
fun getUser(): User {
return user
}
}
接著在 Activity onCreate() 裡面使用 ViewModelProviders
來創建 ViewModel
,就可以使用它裡面的資料了。
class MainActivity : AppCompatActivity() {
private lateinit var viewModel: MainViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel = ViewModelProviders.of(this).get(MainViewModel::class.java)
textView.text = viewModel.getUser().userName //把數據賦值給 UI
}
}
這裡用 this 傳入了一個 Activity
的物件,這是因為當旋轉手機時,Activity
被銷毀,但是 ViewModel
並不會跟著銷毀,(詳情請見 ViewModel 生命週期),而是透過 ViewModelProvider
尋找已經存在的 ViewModel
,並和新生成的 Activity
重新綁定起來。
這樣做的好處是,原本保存在 ViewModel 的數據不會因為 Activity 的銷毀而改變。
使用非常簡單,但是 ViewModel
背後其實做了很多事情來幫助開發者,這些後面會提到。
這邊有些常常會犯的錯誤:
不要將 Context 傳給 ViewModel
這是因為 ViewModel
存在時,對應的 Activity
可能會被多次銷毀,但是透過 ViewModelProviders
來創建的 ViewModel
依然存在,但這時候 ViewModel
卻引用了一個已經被銷毀、不存在的 Context (那個被銷毀的 Activity
),也就是說,出現了內存泄露的問題。
如果真的需要使用 Context,可以使用 AndroidViewModel
這個類,裡面已經含有 Application
這個 Context 的引用。
不要使用
ViewModel
代替onSaveInstanceState
在資源緊缺時,應用程式被系統殺死(這裡和旋轉手機不一樣),ViewModel
也會隨之銷毀,這時候再返回應用程序,UI 數據將不能正常顯示,所以應該還是將一些小量級的數據交由 onSaveInstanceState
保存。
例如:將整個 User 類交給 ViewModel
,onSaveInstanceState
只保存 userId。
到這邊已經懂得如何使用 ViewModel
,但是 ViewModel
厲害之處可不只這些,其他強大的地方會在下一篇提到
有任何問題或講得不清楚的地方歡迎留言和我討論。
更歡迎留言糾正我任何說錯的地方!